package cn.edu.jsu.official.utils;

import fr.opensagres.poi.xwpf.converter.core.BasicURIResolver;
import fr.opensagres.poi.xwpf.converter.core.FileImageExtractor;
import fr.opensagres.poi.xwpf.converter.core.FileURIResolver;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter;
import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.*;

/**
 * @author Mo
 * @createTime 2022/4/24 18:07
 * @description
 */
public class Word2Html {
    private static final Logger logger = LoggerFactory.getLogger(Word2Html.class);


    public static String getFileNameNoEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot >-1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }

    public static String getSystemRoot() {
        String osName = System.getProperty("os.name");
        logger.info("当前系统为: "+osName);
        String windowsUpload = "D:/test/";
        String linuxUpload = System.getProperty("user.dir")+"/upload/";
        if (osName.toLowerCase().startsWith("linux")) {
            return linuxUpload;
        } else if (osName.toLowerCase().startsWith("windows")) {
            return windowsUpload;
        } else {
            throw new RuntimeException("错误目录");
        }
    }

    /**
     * @Author: jimmy
     * @Date: 2019/12/10 10:23
     * @Param: [filePath, fileName, htmlName]
     * @Return: java.lang.String
     * @Description: word转html方法
     */
    public static Map<String, String> Word2HtmlConvert(MultipartFile fileM) throws Exception {
        Map<String, String> stringMap = new HashMap<>();
        String resourcesPath = null;
        // 从MultipartFile 中拿到名字
        String fileName = fileM.getOriginalFilename();
        String suffix=fileName.substring(fileName.lastIndexOf("."));

        String newName= UUID.randomUUID().toString();
        // TODO 需要保存在一个新的位置

//        String filePath = getSystemRoot();
        ArrayList<String> systemRoot = UploadPathUtil.getSystemRoot();
        for (String s : systemRoot) {
            System.out.println(s);
        }
        String filePath = systemRoot.get(0);
        File convFile = new File(filePath + newName +suffix);
        System.out.println(filePath + newName + suffix);
        //写进新文件
        FileOutputStream fos = null;
        try {
            convFile.createNewFile();
            fos = new FileOutputStream(convFile);
            fos.write(fileM.getBytes());
        } catch (IOException ex) {
            logger.error("上传文件出错！", ex);
            return null;
        } finally {
            IOUtils.closeQuietly(fos);
        }

        //获取文件html名称
        //需要报错 抛异常
        String htmlName = fileName.substring(0, fileName.lastIndexOf(".")) + ".html";
        if ((".docx").equals(suffix)) {
            resourcesPath = docx(systemRoot, newName + suffix, htmlName);
        } else if ((".doc").equals(suffix)){
            doc(systemRoot, newName + suffix,  htmlName);
        }
        String readfile = readfile(systemRoot.get(1) + htmlName);
        convFile.delete();
        stringMap.put("html", readfile);
        stringMap.put("resourcesPath", resourcesPath);
        return stringMap;
    }

    /**
     * @Author: jimmy
     * @Date: 2019/12/10 12:34
     * @Param: [filePath, fileName, htmlName]
     * @Return: void
     * @Description: 转换docx
     */
    public static String docx(List<String> filePath , String fileName, String htmlName) throws Exception{
        final String filePathName = filePath.get(0) + fileName;
        String fileNameWithoutExtension = getFileNameNoEx(fileName);
        InputStream in = new FileInputStream(new File(filePathName));
        // 1.加载解析docx文档用的XWPFDocument对象
        XWPFDocument document = new XWPFDocument(in);
        // 2.解析XHTML配置 (这里设置IURIResolver来设置图片存放的目录)
        XHTMLOptions options = XHTMLOptions.create()/*.URIResolver(new FileURIResolver(imageFolderFile))*/;
        options.setIgnoreStylesIfUnused(false);
        options.setFragment(true);
        File imageFolderFile = new File(getFileNameNoEx(filePath.get(1) + fileName));
        System.out.println(filePath.get(1) + fileName);
        options.setExtractor(new FileImageExtractor(imageFolderFile));
        options.URIResolver(new BasicURIResolver("http://10.6.3.104:8888/docResources/" + fileNameWithoutExtension));
        // 3.将 XWPFDocument转换成XHTML
        OutputStream out = new FileOutputStream(new File(filePath.get(1) + htmlName));
        XHTMLConverter.getInstance().convert(document, out, options);
        return getFileNameNoEx(imageFolderFile.getPath());
    }

    /**
     * @Author: jimmy
     * @Date: 2019/12/10 12:34
     * @Param: [filePath, fileName, htmlName]
     * @Return: void
     * @Description: 转换doc
     */
    public static void doc(List<String> filePath ,String fileName, String htmlName) throws Exception{
        final String filePathName = filePath.get(0) + fileName;
        InputStream input = new FileInputStream(new File(filePathName));
        //1.加载解析doc文档用的HWPFDocument对象
        HWPFDocument wordDocument = new HWPFDocument(input);
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
        //解析word文档
        wordToHtmlConverter.processDocument(wordDocument);
        Document htmlDocument = wordToHtmlConverter.getDocument();

        File htmlFile = new File(filePath.get(0) + htmlName);
        OutputStream outStream = new FileOutputStream(htmlFile);

        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(outStream);

        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer serializer = factory.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");
        serializer.setOutputProperty(OutputKeys.METHOD, "html");
        serializer.transform(domSource, streamResult);
        outStream.close();
    }

    /**
     * @Author: jimmy
     * @Date: 2019/12/10 10:20
     * @Param: [filePath]
     * @Return: java.lang.String
     * @Description: 读取poi生成的html文件内容返回
     */
    public static String readfile(String filePath) {
        File file = new File(filePath);
        InputStream input = null;
        try {
            input = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        StringBuffer buffer = new StringBuffer();
        byte[] bytes = new byte[1024];
        try {
            for (int i; (i = input.read(bytes)) != -1;) {
                buffer.append(new String(bytes, 0, i, "utf8"));
            }
            //流记得关闭，不然后面file不能被正常删除
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //转换成功后的html文件内容读取后删掉，防止不必要的占用服务器资源
        file.delete();
        return buffer.toString();
    }
}
